﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Data;

namespace ICodeShare.UI.Converters
{
    #region IValueConverter
    /// <summary>
    /// 枚举值转换成枚举描述
    /// </summary>
    /// <example>
    /// 1.在xmal文件引用DateConverter类所在命名空间。
    ///   xmlns:cvts="http://schemas.extended.wpf.com/converters"
    /// 2.在xaml文件添加Resources。
    ///   <Window.Resources>
    ///   <cvts:BooleanToStringConverter x:Key="cvtsEnumToDescription"/>
    ///   </Window.Resources>
    /// 3.在xaml文件中指定Binding值的Converter
    ///    <TextBox Text="{Binding DeviceState,Converter={StaticResource cvtsEnumToDescription}}"></TextBox>
    ///    <TextBox Text="{Binding DeviceState,Converter={StaticResource cvtsEnumToDescription}}"></TextBox>
    ///    <TextBox Text="{Binding DeviceState,Converter={StaticResource cvtsEnumToDescription}}"></TextBox>
    /// </example>
    /// <remarks>
    /// </remarks>
    [ValueConversion(typeof(Enum), typeof(string))]
    public sealed class EnumToDescriptionConverter : IValueConverter
    {
        #region Constructors 构造函数
        public EnumToDescriptionConverter()
        {
        }
        #endregion

        #region  Base Class Overrides 基类方法重写
        /// <summary>
        /// Converts a value.
        /// </summary>
        /// <param name="value">The value produced by the binding source.</param>
        /// <param name="targetType">The type of the binding target property.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>The converted value.</returns>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is Enum))
            {
                return DependencyProperty.UnsetValue;
            }
            string description = GetDescription(value.GetType(), value.ToString());
            return string.IsNullOrEmpty(description)?value.ToString():description;
        }

        /// <summary>
        /// Converts a value.
        /// </summary>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>The converted value.</returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is string))
            {
                return DependencyProperty.UnsetValue;
            }

           string[] nameArrays = Enum.GetNames(targetType);
           

            if (nameArrays == null || nameArrays.Length <= 0)
                return string.Empty;

            string result = string.Empty;
            foreach (string item in nameArrays)
            {
                string desc = GetDescription(targetType, item);
                if (desc == value.ToString())
                {
                    result = item;
                    break;
                }
            }
            return result;

        }
        #endregion

        private string GetDescription(Type enumType, string enumObjectName)
        {
            FieldInfo[] infoArrays = enumType.GetFields();
            string result = string.Empty;
            foreach (FieldInfo info in infoArrays)
            {
                if (!info.IsSpecialName && info.Name.Equals(enumObjectName, StringComparison.CurrentCultureIgnoreCase))
                {
                    object[] customAttributes = info.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (customAttributes != null && customAttributes.Length > 0)
                    {
                        result = ((DescriptionAttribute)customAttributes[0]).Description;
                        break;
                    }
                }
            }
            if (string.IsNullOrEmpty(result))
            {
                result = enumObjectName;
            }
            return result;
        }
    }
    #endregion
}
